home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr10 / ehp10.zip / MOUSE.C < prev    next >
Text File  |  1993-06-19  |  52KB  |  1,434 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  mouse.c                                         */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*       - Fenster ermitteln, in dem Position liegt (pos_to_win)*/
  7. /*       - Zum Fenster wechseln, in dem Position liegt (sw_pos) */
  8. /*       - Liegt Position innerhalb von akt_winp? (in_akt_win)  */
  9. /*       - Mauscursor verstecken und wieder zeigen (hide_show)  */
  10. /*       - Maus-Status lesen (get_mouse)                        */
  11. /*       - Fenster mit Maus bewegen (mouse_movewin)             */
  12. /*       - Fenstergröße mit Maus ändern (mouse_sizewin)         */
  13. /*       - Bildschirm gemäß Mausposition scrollen (check_scroll)*/
  14. /*       - Cursor setzen oder Block (set_cursor_or_mark_block)  */
  15. /*       - Mausposition in Schaltfäache wandeln (pos_to_button) */
  16. /*       - Fenster mit Maus schließen (mouse_win_zu)            */
  17. /*       - Mit Maus nach rechts scrollen (msr)                  */
  18. /*       - Mit Maus nach links scrollen (msl)                   */
  19. /*       - Mit Maus nach oben scrollen (msu)                    */
  20. /*       - Mit Maus nach unten scrollen (msd)                   */
  21. /*       - Maus-Routine (mouse_routine)                         */
  22. /*       - Maus-Routine für Funktion ja_nein (jn_mouse_routine) */
  23. /*       - Mouse-Interrupt aktivieren/sperren (mouse_jn_init)   */
  24. /*       - Mouse-Interrupt aktivieren/sperren (set_mouse_int)   */
  25. /*       - Maus initialisieren (init_mouse)                     */
  26. /*                                                              */
  27. /****************************************************************/
  28.  
  29. #ifdef OS2
  30.  
  31. #define INCL_DOSPROCESS
  32. #include <os2.h>
  33. #include <stdlib.h>
  34.  
  35. extern HMTX sem_handle; /* Handle für Semaphor */
  36.  
  37. struct MPTRPOS          /* Kann die Position des Mauszeigers aufnehmen */
  38. {
  39.   short int line,
  40.         col;
  41. };
  42.  
  43. #pragma pack(1)
  44. typedef struct MEVENT   /* Nimmt das Mouse-Event aus der Event-Queue auf */
  45. {
  46.   short int button_status; /* Bit 2 links, Bit 4 rechts */
  47.   int       time;
  48.   short int y,
  49.         x;
  50. } mouse_type;
  51. #pragma pack(4)
  52.  
  53. short int mouse_handle; /* Globale Variable enthält den Mouse-Handle */
  54. TID       mouse_ThreadID, /* Hier steht die ID des Mouse-Threads */
  55.       mouse_jn_ThreadID=0; /* Mouse-Thread für ja_nein-Abfrage */
  56. char      mouse_jn_active = FALSE, /* Routine ja_nein aktiv ? */
  57.       mouse_active = FALSE;    /* Soll Mouse_Thread laufen ? */
  58.  
  59. #else
  60.  
  61. #pragma inline
  62. #include <dos.h>
  63. typedef struct mouse_struct
  64. {
  65.   int button_status,  /* Knopfstatus: Bit 0 links, Bit 1 rechts, Bit 2 Mitte */
  66.       x,              /* X-Position (0..COLS-1) */
  67.       y;              /* Y-Position (0..LINES-1) */
  68. } mouse_type;
  69.  
  70.  
  71. #endif
  72.  
  73. #include "defs.h"
  74.  
  75. extern (*funktion[])(),
  76.        do_win_zu();
  77. extern short int mc_index;
  78. extern comm_typ *comm_feld;
  79. extern char highblockflag;
  80.  
  81. int mouse_jn;         /* Variable für Bedienung der Funktion ja_nein mit
  82.              der Maus. Kann die Werte NO_KLICK, KLICK_RIGHT und
  83.              KLICK_LEFT annehmen. */
  84.  
  85. /******************************************************************************
  86. 
  87.  Funktion     : Fenster ermitteln, in dem Position liegt (pos_to_win)
  88.  --------------
  89. 
  90.  Parameter    : x           :
  91.                   Typ          : int
  92.                   Wertebereich : 0-COLS
  93.                   Bedeutung    : X-Achse der Position
  94. 
  95.                 y           :
  96.                   Typ          : int
  97.                   Wertebereich : 0-LINES
  98.                   Bedeutung    : Y-Achse der Position
  99. 
  100.  Ergebnis     :
  101. *                  Typ          : win_typ *
  102. *                  Wertebereich : Pointer auf Fensterstruktur
  103. *                  Bedeutung    : Zeigt auf das sichtbare Fenster, in dem die
  104. *                                 angegebene Position liegt
  105. *
  106. * Beschreibung : Es werden in der Reihenfolge. in der sie beim Refresh
  107. *                gezeichnet würden, alle Fenster durchgegangen und der Zeiger
  108. *                auf das Fenster gemerkt, falls die angegebene Position in
  109. *                dem getesteten Fenster liegt. So erhält man das Fenster,
  110. *                in dem die übergebene Position liegt.
  111. *
  112. ******************************************************************************/
  113.  
  114. win_typ *pos_to_win(x,y)
  115. int x,y;
  116. {
  117.   win_typ *w,          /* Pointer zum Durchlaufen der Fensterliste */
  118.       *res = NULL; /* Pointe auf Fenster, in dem Position liegt */
  119.  
  120.   for(w=akt_winp->next->next; w != akt_winp->next; w=w->next)
  121.     /* Alle Fenster durchlaufen */
  122.     if(x >= w->x && x <= w->x + w->dx + 1
  123.     && y >= w->y && y <= w->y + w->dy + 1)
  124.       res = w;  /* Position liegt im Fenster, Fenster merken */
  125.   return(res);
  126. }
  127.  
  128. /******************************************************************************
  129. *
  130. * Funktion     : Zum Fenster wechseln, in dem Position liegt (sw_pos)
  131. * --------------
  132. *
  133. * Parameter    : x           :
  134. *                  Typ          : int
  135. *                  Wertebereich : 0-COLS
  136. *                  Bedeutung    : X-Achse der Position
  137. *
  138. *                y           :
  139. *                  Typ          : int
  140. *                  Wertebereich : 0-LINES
  141. *                  Bedeutung    : Y-Achse der Position
  142. *
  143. * Ergebnis     :
  144. *                  Typ          : int
  145. *                  Wertebereich : TRUE, FALSE
  146. *                  Bedeutung    : TRUE: Fenster gefunden, FALSE: nicht gefunden
  147. *
  148. * Beschreibung : Mittels der Funktion pos_to_win wird das Fenster ermittelt,
  149. *                in dem die Position liegt. Wird ein solches Fenster gefunden,
  150. *                so wird es zum aktuellen gemacht und TRUE geliefert, ansonsten
  151. *                wird FALSE geliefert.
  152. *
  153. ******************************************************************************/
  154.  
  155. int sw_pos(x,y)
  156. int x,y;
  157. {
  158.   win_typ *w, /* Zeiger auf zu aktivierendes Fenster */
  159.       *dummy;
  160.  
  161.   if(w = pos_to_win(x,y))  /* Liegt die Position in einem sichtbaren Fenster ? */
  162.   {
  163.     if(w != akt_winp)
  164.     {
  165.       dummy = akt_winp->next;   /* Dann gefundenes Fenster zum aktuellen */
  166.       akt_winp->next = w;       /* machen, indem man es vor dummy in     */
  167.       w->prev->next = w->next;  /* die Fensterliste einhaengt.           */
  168.       w->next->prev = w->prev;
  169.       w->prev = akt_winp;
  170.       w->next = dummy;
  171.       dummy->prev = w;
  172.       akt_winp = w;
  173.     }
  174.     return(TRUE);
  175.   }
  176.   return(FALSE); /* Position lag nicht in einem Fenster */
  177. }
  178.  
  179. /******************************************************************************
  180. *
  181. * Funktion     : Liegt Position innerhalb von akt_winp? (in_akt_win)
  182. * --------------
  183. *
  184. * Parameter    : x           :
  185. *                  Typ          : int
  186. *                  Wertebereich : 0-MAXINT
  187. *                  Bedeutung    : X-Position, die zu testen ist
  188. *
  189. *                y           :
  190. *                  Typ          : int
  191. *                  Wertebereich : 0-MAXINT
  192. *                  Bedeutung    : Y-Position, die zu testen ist
  193. *
  194. * Ergebnis     :
  195. *                  Typ          : int
  196. *                  Wertebereich : TRUE, FALSE
  197. *                  Bedeutung    : TRUE: Position liegt im aktuellen Fenster
  198. *                                 FALSE: Position liegt nicht im aktuellen
  199. *                                        Fenster
  200. *
  201. * Beschreibung : Die übergebenen Koordinaten werden mit den Koordinaten
  202. *                des aktuellen Fensters verglichen. Liegen sie innerhalb,
  203. *                also in der Textfläche, so wird TRUE, sonst FALSE ge-
  204. *                liefert.
  205. *
  206. ******************************************************************************/
  207.  
  208. int in_akt_win(x,y)
  209. int x,y;
  210. {
  211.   return(x > akt_winp->x && x <= akt_winp->x+akt_winp->dx
  212.   && y > akt_winp->y && y <= akt_winp->y+akt_winp->dy);
  213. }
  214.  
  215. /******************************************************************************
  216. *
  217. * Funktion     : Mauscursor verstecken und wieder zeigen (hide_show)
  218. * --------------
  219. *
  220. * Parameter    : hs          :
  221. *                  Typ          : int
  222. *                  Wertebereich : MOUSE_SHOW, MOUSE_HIDE,
  223. *                  Bedeutung    : MOUSE_HIDE : Mauszeiger verstecken
  224. *                                 MOUSE_SHOW : Mauszeiger anzeigen
  225. *
  226. * Beschreibung : Der Mauscursor wird mit der Funktion 2 des Mausinterrupts
  227. *                versteckt, falls MOUSE_HIDE gesetzt war, und anschließend
  228. *                mit der Funktion 1 wieder dargestellt, falls MOUSE_SHOW
  229. *                gesetzt war. War der Mauscursor also vorher eingeschal-
  230. *                tet, so ist dann garantiert, daß er auch sichtbar ist.
  231. *                Das ist wichtig, falls nach einem Refresh der Mauscursor
  232. *                sichtbar sein soll.
  233. *
  234. ******************************************************************************/
  235.  
  236. void hide_show(hs)
  237. int hs;
  238. {
  239. #ifdef OS2
  240.   static struct MOUREMOVESTRUCT
  241.   {
  242.      short int startline,
  243.            startcol,
  244.            endline,
  245.            endcol;
  246.   } mrs;
  247.   static char need_init = TRUE;
  248.  
  249.   if (hs & MOUSE_HIDE)
  250.   {
  251.     if (need_init)
  252.     {
  253.       mrs.startline = mrs.startcol = 0;
  254.       mrs.endline   = LINES-1;
  255.       mrs.endcol    = COLS-1;
  256.       need_init     = FALSE;
  257.     }
  258.     MouRemovePtr (&mrs, mouse_handle);
  259.   }
  260.   if (hs & MOUSE_SHOW)
  261.     MouDrawPtr (mouse_handle);
  262. #else
  263.   union  REGS  regs;
  264.  
  265.   if(hs & MOUSE_HIDE)
  266.   {
  267.     regs.x.ax = 2;
  268.     int86(51,®s,®s);
  269.   }
  270.   if(hs & MOUSE_SHOW)
  271.   {
  272.     regs.x.ax = 1;
  273.     int86(51,®s,®s);
  274.   }
  275. #endif
  276. }
  277.  
  278. #ifndef OS2
  279. /*******************************************************************************
  280. 
  281. * Funktion     : Maus-Status lesen (get_mouse)
  282. * --------------
  283. *
  284. * Ergebnis     :
  285. *                  Typ          : *mouse_type
  286. *                  Wertebereich : Pointer auf Maus-Struktur
  287. *                  Bedeutung    : Zeigt auf Struktur, die die aktuellen
  288. *                                 Mausdaten enthält.
  289. *
  290. * Beschreibung : Mittels der Funktion 3 des Mausinterrupts wird der Mausstatus
  291. *                eingelesen.
  292. *
  293. ******************************************************************************/
  294.  
  295. mouse_type *get_mouse()
  296. {
  297.   static mouse_type m; /* zur Ablage des Maus-Status */
  298.   union  REGS  regs;
  299.  
  300.   regs.x.ax  = 3;
  301.   int86(51,®s,®s);
  302.   m.button_status = regs.x.bx;
  303.   m.x             = regs.x.cx / 8;
  304.   m.y             = regs.x.dx / 8;
  305.   return(&m);
  306. }
  307. #endif
  308.  
  309. /******************************************************************************
  310. *
  311. * Funktion     : Fenster mit Maus bewegen (mouse_movewin)
  312. * --------------
  313. *
  314. * Parameter    : m           :
  315. *                  Typ          : mouse_type *
  316. *                  Wertebereich : Pointer aus Mausstruktur
  317. *                  Bedeutung    : Mauszustand mit Position und Knopfdrücken
  318. *
  319. * Beschreibung : Das aktuelle Fenster wird durch die Maus verschoben.
  320. *                Die Mauskoordinaten werden solange geprüft, bis der
  321. *                linke Mausknopf nicht mehr gedrückt ist. Dann wird
  322. *                das Fenster in seiner dortigen Position gezeichnet.
  323. *
  324. ******************************************************************************/
  325.  
  326. void mouse_movewin(m)
  327. mouse_type *m;
  328. {
  329.   int old_x = m->x, /* Ablage für alte Mauskoordinaten */
  330.       old_y = m->y,
  331.       moved = FALSE;
  332. #ifdef OS2
  333.   short int wait = 1; /* Auf Mausereignisse warten */
  334. #endif
  335.  
  336.   /* Wenn rechter Mausknopf gedrückt wurde, dann Fenster in den Hintergrund
  337.      schieben. Bei linkem Mausknopf evtl. Fenster verschieben. */
  338.   if(m->button_status & MOUSE_BUT2) /* rechter Knopf ? */
  339.   {
  340.     hide_show(MOUSE_HIDE); /* Mauszeiger verstecken */
  341.     push_win_back(); /* Fenster zum hintersten machen */
  342.     do_refresh();
  343.     hide_show(MOUSE_SHOW); /* Mauszeiger wieder anzeigen */
  344.   }
  345.   else /* linker Mausknopf war gedrückt */
  346.   {
  347.     /* warten, bis entweder der Mausknopf losgelassen wird, oder */
  348.     /* die Maus bewegt wird. */
  349. #ifdef OS2
  350.     MouReadEventQue (m, &wait, mouse_handle);
  351.     while (m->button_status & (MOUSE_BUT1_MOVE | MOUSE_BUT1))
  352.     {  /* Maus wurde mit gedrücktem linken Knopf bewegt. */
  353. #else
  354.     while((m=get_mouse())->button_status & MOUSE_BUT1)
  355.     {
  356.       if(m->x != old_x || m->y != old_y)  /* Maus wurde mit gedrücktem Knopf */
  357.       {                                   /* bewegt. */
  358. #endif
  359.     hide_show(MOUSE_HIDE);
  360.     if(!moved)
  361.     {
  362.       moved = TRUE;
  363.       werase (akt_winp->winp);  /* Fensterinhalt auf Bildschirm loeschen */
  364.       wrefresh(akt_winp->winp); /* damit kein Fehler beim Verschieben passiert */
  365.       cpwins2stdscr(); /* Alle Fenster ausser akt. nach stdscr kopieren */
  366.     }
  367.     else
  368.       eckenhw();                 /* Ecken des Fensters demarkieren      */
  369.     if(m->x > old_x)
  370.       win_right(m->x - old_x);
  371.     else
  372.       win_left(old_x - m->x);
  373.     if(m->y > old_y)
  374.       win_down(m->y - old_y);
  375.     else
  376.       win_up(old_y - m->y);
  377.     old_x = m->x; /* Mauskoordinaten merken */
  378.     old_y = m->y;
  379.     eckenhw();                   /* Ecken markieren */
  380.     hide_show(MOUSE_SHOW);
  381. #ifdef OS2
  382.       MouReadEventQue (m, &wait, mouse_handle);
  383. #else
  384.       }
  385. #endif
  386.     }
  387.     if(moved)    /* Falls Fenster verschoben wurde, Ecken wieder löschen */
  388.     {            /* und Fenster neu zeichnen */
  389.       hide_show(MOUSE_HIDE);
  390.       eckenhw();
  391.       erase();
  392.       refresh();
  393.       mvwin (akt_winp->winp,akt_winp->y,akt_winp->x); /* Fenster verschieben */
  394.       do_refresh();                   /* Alle Fenster neu zeichnen           */
  395.       hide_show(MOUSE_SHOW);
  396.     }
  397.   }
  398. }
  399.  
  400. /******************************************************************************
  401. *
  402. * Funktion     : Fenstergröße mit Maus ändern (mouse_sizewin)
  403. * --------------
  404. *
  405. * Parameter    : m           :
  406. *                  Typ          : mouse_type *
  407. *                  Wertebereich : Pointer aus Mausstruktur
  408. *                  Bedeutung    : Mauszustand mit Position und Knopfdrücken
  409. *
  410. * Beschreibung : Das aktuelle Fenster wird durch die Maus vergrößert
  411. *                oder verkleinert.
  412. *                Die Mauskoordinaten werden solange geprüft, bis der
  413. *                linke Mausknopf nicht mehr gedrückt ist. Dann wird
  414. *                das Fenster in seiner dortigen Größe gezeichnet.
  415. *
  416. ******************************************************************************/
  417.  
  418. void mouse_sizewin(m)
  419. mouse_type *m;
  420. {
  421.   int old_x = m->x, /* Ablage für alte Mauskoordinaten */
  422.       old_y = m->y,
  423.       moved = FALSE;
  424. #ifdef OS2
  425.   short int wait = 1; /* auf Mausereignisse warten */
  426. #endif
  427.  
  428.   /* warten, bis entweder der Mausknopf losgelassen wird, oder */
  429.   /* die Maus bewegt wird. */
  430. #ifdef OS2
  431.   MouReadEventQue (m, &wait, mouse_handle);
  432.   while (m->button_status & (MOUSE_BUT1_MOVE | MOUSE_BUT2_MOVE
  433.                | MOUSE_BUT1 | MOUSE_BUT2))
  434.   {
  435. #else
  436.   while((m=get_mouse())->button_status & (MOUSE_BUT1 | MOUSE_BUT2))
  437.   {
  438.     if(m->x != old_x || m->y != old_y)  /* Maus wurde mit gedrücktem Knopf */
  439.     {                                   /* bewegt. */
  440. #endif
  441.       hide_show(MOUSE_HIDE);
  442.       if(!moved)
  443.       {
  444.     moved = TRUE;
  445.     werase (akt_winp->winp);  /* Fensterinhalt auf Bildschirm loeschen */
  446.     wrefresh(akt_winp->winp); /* damit kein Fehler beim Verschieben passiert */
  447.     cpwins2stdscr(); /* Alle Fenster ausser akt. nach stdscr kopieren */
  448.       }
  449.       else
  450.     eckenhw();                 /* Ecken des Fensters demarkieren      */
  451.       if(m->x > old_x)
  452.     size_right(m->x - old_x);
  453.       else
  454.     size_left(old_x - m->x);
  455.       if(m->y > old_y)
  456.     size_down(m->y - old_y);
  457.       else
  458.     size_up(old_y - m->y);
  459.       old_x = m->x; /* Mauskoordinaten merken */
  460.       old_y = m->y;
  461.       eckenhw();                   /* Ecken markieren */
  462.       hide_show(MOUSE_SHOW);
  463. #ifdef OS2
  464.     MouReadEventQue (m, &wait, mouse_handle);
  465. #else
  466.     }
  467. #endif
  468.   }
  469.   if(moved)    /* Falls Fenster verschoben wurde, Ecken wieder löschen */
  470.   {            /* und Fenster neu zeichnen */
  471.     hide_show(MOUSE_HIDE);
  472.     eckenhw();
  473.     erase();                  /* gedrueckt wurde (RETURN) */
  474.     refresh();                /* Fensterinhalt loeschen */
  475.     delwin(akt_winp->winp);   /* Fenster mit Curses loeschen und neu anlegen */
  476.     akt_winp->winp=newwin(akt_winp->dy+2,akt_winp->dx+2,akt_winp->y,akt_winp->x);
  477.     init_win();               /* Fensterattribute setzen (raw etc.) */
  478.  
  479.     /* Falls Cursor jetzt ausserhalb des Fensters steht, Cursorposition anpassen */
  480.     if (akt_winp->ws_line+akt_winp->dy <= akt_winp->textline)
  481.       gotox(akt_winp->ws_line+akt_winp->dy-1);
  482.     if (akt_winp->ws_col+akt_winp->dx <= akt_winp->screencol)
  483.       akt_winp->screencol = akt_winp->ws_col+akt_winp->dx-1;
  484.     do_refresh();  /* Alle Fenster neu zeichnen */
  485.     hide_show(MOUSE_SHOW);
  486.   }
  487. }
  488.  
  489. /******************************************************************************
  490. *
  491. * Funktion     : Bildschirm gemäß Mausposition scrollen (check_scroll)
  492. * --------------
  493. *
  494. * Parameter    : m           :
  495. *                  Typ          : mouse_type *
  496. *                  Wertebereich : Pointer auf Mausstruktur
  497. *                  Bedeutung    : Mausstatus
  498. *
  499. * Beschreibung : Die Mausposition liegt außerhalb des aktuellen Fensters.
  500. *                Der Fensterinhalt soll in Richtung des Mauscursors an-
  501. *                gepaßt werden. Steht also beispielsweise die Maus unter-
  502. *                halb des aktuellen Fensters, so soll der Text im Fenster
  503. *                nach oben geschoben werden (damit z.B. auch fensterüber-
  504. *                greifende Blöcke markiert werden können.
  505. *
  506. ******************************************************************************/
  507.  
  508. void check_scroll(m)
  509. mouse_type *m;
  510. {
  511.   /* Zuerst die Verschiebung nach oben/unten testen */
  512.   if(m->y < akt_winp->y+1
  513.   && akt_winp->ws_line) /* Verschiebung des Inhalts nach unten */
  514.   {
  515.     akt_winp->ws_line--; /* dann Nummer der ersten sichtbaren Zeile erhoehen */
  516.     text_down(0);        /* gesamten Fenstertext um 1 Zeile nach unten */
  517.     up();                /* Cursor um 1 Zeile nach oben bewegen */
  518.     setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  519.   }
  520.   else
  521.     if(m->y > akt_winp->y+akt_winp->dy /* Verschiebung der Inhalts nach */
  522.     && akt_winp->ws_line < akt_winp->maxline) /* oben */
  523.     {
  524.       akt_winp->ws_line++; /* dann Nummer der ersten sichtbaren Zeile erhoehen */
  525.       text_up(0);          /* gesamten Fenstertext um 1 Zeile nach oben */
  526.       down();              /* Cursor um 1 Zeile nach unten bewegen */
  527.       setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  528.     }
  529.  
  530.   /* Jetzt Verschiebung nach rechts/links testen */
  531.   if(m->x < akt_winp->x+1
  532.   && akt_winp->ws_col)  /* Verschiebung des Inhalts nach rechts */
  533.   {
  534.     text_right();
  535.     left();
  536.     setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  537.   }
  538.   else
  539.     if(m->x > akt_winp->x+akt_winp->dx
  540.     && akt_winp->ws_col < MAXLENGTH)
  541.     {
  542.       text_left();
  543.       right();
  544.       setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  545.     }
  546. }
  547.  
  548. /******************************************************************************
  549. *
  550. * Funktion     : Blockende setzen (mouse_blend)
  551. * --------------
  552. *
  553. * Parameter    : m           :
  554. *                  Typ          : mouse_type *
  555. *                  Wertebereich : Pointer auf Mausstruktur
  556. *                  Bedeutung    : Mauszustand
  557. *
  558. *              : old_x       :
  559. *                  Typ          : int
  560. *                  Wertebereich : 0-COLS
  561. *                  Bedeutung    : Alte Mausposition Spalte
  562. *
  563. *              : old_y       :
  564. *                  Typ          : int
  565. *                  Wertebereich : 0-LINES
  566. *                  Bedeutung    : Alte Mausposition Zeile
  567. *
  568. *              : bl_typ      :
  569. *                  Typ          : char
  570. *                  Wertebereich : BT_RECHTECK, BT_NORMAL
  571. *                  Bedeutung    : Blocktyp
  572. *
  573. *              : need_show_win:
  574. *                  Typ          : char
  575. *                  Wertebereich : TRUE, FALSE
  576. *                  Bedeutung    : Wenn TRUE, muß statt der Anzeige der Zeilen
  577. *                                 zwischen alter und neuer Mausposition
  578. *                                 ein show_win ausgeführt werden.
  579. *
  580. * Beschreibung : Die Maus wurde mit gedrücktem Mausknopf von der Position
  581. *                old_x/old_y nach der von m angegebenen Position verschoben.
  582. *                An der neuen Position muß also nun das Blockende gesetzt
  583. *                werden und der so entstandene neue Block gehighlighted
  584. *                werden, falls die Blockhervorhebung aktiviert ist.
  585. *                Dazu werden die Zeilen zwischen dem alten Blockende (old_y)
  586. *                und dem neuen Blockende (m->y) mittels lineout neu
  587. *                angezeigt.
  588. *
  589. ******************************************************************************/
  590.  
  591. void mouse_blend (mouse_type *m, int old_x, int old_y,
  592.           char bl_typ, char need_show_win)
  593. {
  594.   int y, /* Fensterzeile, in der aktuelle Zeile angezeigt wird */
  595.       i, /* zählt die Zeilen, um die sich Maus bewegt hat. */
  596.       old_tl = akt_winp->textline, /* zur Restaurierung nötig */
  597.       woy,  wy,   /* Mauskoordinaten in Bezug auf das Window */
  598.       first_l, last_l, /* bei rechteckigem Block: 1. und */
  599.                /* letzte anzuzeigende Zeile      */
  600.       direction_dn; /* FALSE für Mausbewegung nach oben, TRUE für
  601.                Mausbewegung nach unten oder Stillstand */
  602.   char block_got_unmarked;  /* Wurde Block bei dieser Aktion unmarkiert? */
  603.  
  604.   /* Prüfen, ob Block durch diese Aktion einen negativen Zeilenumfang
  605.      erhält. Dann ist nämlich auch eine Nachbesserung vorzunehmen */
  606.   if (akt_winp->block.e_line >= akt_winp->block.s_line
  607.   &&  akt_winp->textline < akt_winp->block.s_line)
  608.     block_got_unmarked = TRUE;
  609.   else
  610.     block_got_unmarked = FALSE;
  611.  
  612.   akt_winp->block.e_line = akt_winp->textline; /* Zeile und Spalte als Block- */
  613.   akt_winp->block.e_col = akt_winp->screencol; /* ende eintragen              */
  614.   akt_winp->block.typ = bl_typ;                /* Blocktyp eintragen          */
  615.   if (need_show_win)
  616.     show_win (W_AKT);
  617.   else
  618.   {
  619.     /* Wenn Block zu highlighten ist und (der Block Zeilenumfang >= 0 hat
  620.        oder gerade durch diesen Aufruf negativen Zeilenumfang erhält),
  621.        dann ist die Blockdarstellung nachzubessern. */
  622.     if (highblockflag &&
  623.     (akt_winp->block.s_line <= akt_winp->block.e_line || block_got_unmarked))
  624.     {
  625.       if (bl_typ == BT_NORMAL  /* bei normalem Block und bei rechteckigem   */
  626.       ||  m->x == old_x) /* Block, falls sich die x-Position nicht geändert */
  627.       { /* hat, müssen nur die Zeilen, die von der Maus überstrichen wurden,*/
  628.     /* neu angezeigt werden. */
  629.     direction_dn = m->y >= old_y;
  630.     y = akt_winp->textline - akt_winp->ws_line;
  631.     for (i=m->y; direction_dn ? i >= old_y : i <= old_y;
  632.          direction_dn ? i-- : i++)
  633.     {
  634.       lineout (direction_dn ? y-- : y++);
  635.       direction_dn ? up() : down();
  636.     }
  637.       }
  638.       else /* bei rechteckigem Block müssen alle sichtbaren Blockzeilen neu */
  639.       { /* angezeigt werden, falls sich die x-Koordinate geändert hat.
  640.        Es wird immer mit der ersten sichtbaren Blockzeile begonnen und
  641.        von dort aus nach unten gegangen. */
  642.     woy = akt_winp->ws_line-1-akt_winp->y+old_y; /* umrechnen in       */
  643.     wy  = akt_winp->ws_line-1-akt_winp->y+m->y;  /* Form               */
  644.     if (woy < wy) { first_l = woy; last_l  = wy;  }
  645.     else          { first_l = wy;  last_l  = woy; }
  646.     if (akt_winp->block.s_line < akt_winp->ws_line) /* Block beginnt */
  647.       first_l = akt_winp->ws_line;           /* oberhalb von Fenster */
  648.     else /* beginnt Block oberhalb von Mausbewegungsbereich ? */
  649.       if (akt_winp->block.s_line < first_l)
  650.         first_l = akt_winp->block.s_line;
  651.     if (akt_winp->block.e_line > last_l)
  652.       last_l = akt_winp->block.e_line;
  653.     /* Jetzt liegt first_l und last_l im Fenster */
  654.     gotox (first_l);
  655.     y = akt_winp->textline - akt_winp->ws_line;
  656.     for (i=first_l; i<=last_l; i++, down())
  657.       lineout (y++);
  658.       }
  659.       gotox (old_tl);
  660.     }
  661.     setz_cursor (W_AKT);
  662.   }
  663. }
  664.  
  665. /******************************************************************************
  666. *
  667. * Funktion     : Cursor setzen oder Block markieren (set_cursor_or_mark_block)
  668. * --------------
  669. *
  670. * Parameter    : m           :
  671. *                  Typ          : mouse_type *
  672. *                  Wertebereich : Pointer auf Mausstruktur
  673. *                  Bedeutung    : Mauszustand
  674. *
  675. * Beschreibung : Wird der Mausknopf ohne Mausbewegung losgelassen, dann
  676. *                wird lediglich der Cursor auf die Mausposition gesetzt.
  677. *                Wird die Maus jedoch mit gedrücktem Mausknopf bewegt,
  678. *                dann wird damit ein Block markiert.
  679. *
  680. ******************************************************************************/
  681.  
  682. void set_cursor_or_mark_block(m)
  683. mouse_type *m;
  684. {
  685. #ifdef OS2
  686.   short int wait = 1; /* auf Mausereignisse warten */
  687.   mouse_type old_event; /* Damit bei leerem Event Position nicht weg ist */
  688. #endif
  689.   int old_x = m->x, /* Ablage für alte Mauskoordinaten */
  690.       old_y = m->y;
  691.   int old_button = m->button_status, /* Zwischenspeicher für Knöpfe */
  692.       moved = FALSE;
  693.   char event_valid = TRUE, /* Wird auf FALSE gesetzt, wenn in OS/2 leeres
  694.                   Mouse-Event auftritt (bei wait=0 möglich) */
  695.        need_show_win = TRUE; /* wird TRUE, wenn in mouse_bl...end nicht
  696.                 nur die Zeilen zwischen alter und neuer
  697.                 Mausposition neu angezeigt werden müssen,
  698.                 sondern ein show_win notwendig geworden ist. */
  699.  
  700.   /* zunächst wird der Cursor an die Mausposition gesetzt */
  701.   gotox(akt_winp->ws_line + m->y - 1 - akt_winp->y);
  702.   akt_winp->screencol = akt_winp->ws_col + m->x - 1 - akt_winp->x;
  703.   hide_show (MOUSE_HIDE);
  704.   setz_cursor(W_AKT);
  705.   hide_show (MOUSE_SHOW);
  706.   /* warten, bis entweder der Mausknopf losgelassen wird, oder */
  707.   /* die Maus bewegt wird. */
  708. #ifdef OS2
  709.   MouReadEventQue (m, &wait, mouse_handle);
  710.   /* solange, wie die Maus bewegt wird, oder kein Mausereignis stattgefunden
  711.      hat (nur bei wait==0 möglich) die Blockgrößen anpassen. */
  712.   while ((m->button_status & (MOUSE_BUT1_MOVE | MOUSE_BUT2_MOVE
  713.                 | MOUSE_BUT1 | MOUSE_BUT2))
  714.     || (!wait && !m->button_status && !m->time && !m->x && !m->y))
  715.   {
  716.     if (!wait && !m->button_status && !m->time && !m->x && !m->y)
  717.       event_valid = FALSE;  /* leeres Event gelesen bei wait=0 */
  718.     else
  719.     {
  720.       old_event = *m;      /* gültige Events werden gemerkt */
  721.       event_valid = TRUE;
  722.     }
  723. #else
  724.   while((m=get_mouse())->button_status & (MOUSE_BUT1 | MOUSE_BUT2))
  725.   {
  726. #endif
  727.     if(event_valid && in_akt_win(m->x,m->y)) /* Innerhalb des Fenster ? */
  728.     {
  729. #ifdef OS2
  730.       wait = 1; /* Innerhalb auf Mausereignis warten */
  731. #endif
  732.       if(m->x != old_x || m->y != old_y)  /* Maus wurde mit gedrücktem Knopf */
  733.       {                                   /* bewegt: */
  734.     hide_show(MOUSE_HIDE);
  735.     if(!moved) /* Falls erste Bewegung: */
  736.     {
  737.       moved = TRUE;
  738.       /* Jetzt Blockanfang auf die alte Cursorposition setzen */
  739.       do_blstart();
  740.       /* Dann Cursor auf neue Position setzen */
  741.       gotox(akt_winp->ws_line + m->y - 1 - akt_winp->y);
  742.       akt_winp->screencol = akt_winp->ws_col + m->x - 1 - akt_winp->x;
  743.     }
  744.     else
  745.     {
  746.       gotox(akt_winp->ws_line + m->y - 1 - akt_winp->y);
  747.       akt_winp->screencol = akt_winp->ws_col + m->x - 1 - akt_winp->x;
  748.     }
  749. #ifdef OS2
  750.     if(m->button_status & MOUSE_BUT1_MOVE)
  751. #else
  752.     if(m->button_status & MOUSE_BUT1) /* Bei linkem Knopf normaler Block */
  753. #endif
  754.       mouse_blend(m, old_x, old_y, BT_NORMAL, need_show_win);
  755.     else                     /* Bei rechtem Knopf rechteckiger Block */
  756.       mouse_blend(m, old_x, old_y, BT_RECHTECK, need_show_win);
  757.     hide_show(MOUSE_SHOW);
  758.     old_x = m->x; /* neue Mauskoordinaten merken */
  759.     old_y = m->y;
  760.     need_show_win = FALSE; /* Block wurde richtig angezeigt, */
  761.       } /* also muß beim nächsten mal nur die Differenz gezeigt  */
  762.     }   /* werden */
  763.     else /* Maus steht außerhalb des Fensters */
  764.     { /* Jetzt muß evtl. der Fensterinhalt gescrollt werden. */
  765.       need_show_win = TRUE;  /* beim nächsten Blockendesetzen muß */
  766.       hide_show(MOUSE_HIDE); /* das Fenster neu gezeichnet werden */
  767.       check_scroll(
  768. #ifdef OS2
  769.            &old_event);
  770. #else
  771.            m);
  772. #endif
  773.       hide_show(MOUSE_SHOW);   /* Mauscursor wieder sichtbar machen */
  774. #ifdef OS2
  775.       wait = 0; /* Solange Maus außerhalb des Fensters steht, nicht auf */
  776.         /* Mausereignis warten, sondern ständig scrollen. */
  777. #endif
  778.       old_x = m->x; /* neue Mauskoordinaten merken */
  779.       old_y = m->y;
  780.     }
  781. #ifdef OS2
  782.     MouReadEventQue (m, &wait, mouse_handle);
  783. #endif
  784.   }
  785.   if(!moved)
  786.     if(old_button & MOUSE_BUT2) /* Wenn der Mauszeiger nicht mit */
  787.     { /* gedrücktem Knopf bewegt wurde und der rechte Knopf gedrückt war: */
  788.       hide_show(MOUSE_HIDE);
  789.       if(block_defined()) /* Wenn im aktuellen Fenster ein Block markiert ist, */
  790.       {                    /* und neben dem rechten noch der mittlere Knopf */
  791.     if(old_button & MOUSE_BUT3) /* gedrückt war, dann Block löschen */
  792.       do_blweg();
  793.     else             /* Wenn nur der rechte Knopf gedrückt war, */
  794.     {
  795.       do_blcut();    /* dann diesen Cutten */
  796.       do_blunmark(); /* und anschließend unmarkieren */
  797.     }
  798.       }
  799.       else          /* Ist jedoch kein Block markiert, dann Pasten */
  800.     do_blpaste();
  801.       hide_show(MOUSE_SHOW);
  802.     }
  803.     else
  804.       if((old_button & (MOUSE_BUT1 | MOUSE_BUT3)) 
  805.       == (MOUSE_BUT1 | MOUSE_BUT3))
  806.       { /* linker und mittlerer Knopf gedrückt ? */
  807.     hide_show(MOUSE_HIDE);
  808.     do_blmove();
  809.     hide_show(MOUSE_SHOW);
  810.       }
  811. }
  812.  
  813. /******************************************************************************
  814. *
  815. * Funktion     : Mausposition in Schaltfäache wandeln (pos_to_button)
  816. * --------------
  817. *
  818. * Parameter    : m           :
  819. *                  Typ          : mouse_type *
  820. *                  Wertebereich : Pointer auf Mausstruktur
  821. *                  Bedeutung    : Mausstatus
  822. *
  823. * Ergebnis     :
  824. *                  Typ          : int
  825. *                  Wertebereich : MOUSE_...
  826. *                  Bedeutung    : Bezeichner der Schaltfläche
  827. *
  828. * Beschreibung : Die Mausposition wird mit der Lage der Schaltflächen
  829. *                verglichen und die entsprechende Schaltfläche
  830. *                zurückgeliefert.
  831. *
  832. ******************************************************************************/
  833.  
  834. int pos_to_button(m)
  835. mouse_type *m;
  836. {
  837.   if(in_akt_win(m->x,m->y))
  838.     return(MOUSE_TEXT); /* Maus steht im Textbereich */
  839.   if(m->x == akt_winp->x && m->y == akt_winp->y)
  840.     return(MOUSE_CLOSE); /* linke obere Ecke: Schließknopf */
  841.   if(m->x == akt_winp->x+akt_winp->dx+1 && m->y == akt_winp->y)
  842.     return(MOUSE_TOG_SIZE);
  843.   if(m->x == akt_winp->x+akt_winp->dx+1 
  844.   && m->y == akt_winp->y+akt_winp->dy+1)
  845.     return(MOUSE_SIZE);
  846.   if(m->y == akt_winp->y)
  847.     return(MOUSE_KOPF);
  848.   if(m->x == akt_winp->x+akt_winp->dx+1)
  849.     if(m->y == akt_winp->y+1)
  850.       return(MOUSE_SCROLL_DOWN);
  851.     else
  852.       if(m->y == akt_winp->y+akt_winp->dy)
  853.     return(MOUSE_SCROLL_UP);
  854.   if(m->y == akt_winp->y+akt_winp->dy+1)
  855.     if(m->x == akt_winp->x+1)
  856.       return(MOUSE_SCROLL_RIGHT);
  857.     else
  858.       if(m->x == akt_winp->x+akt_winp->dx)
  859.     return(MOUSE_SCROLL_LEFT);
  860.   return(MOUSE_RAHMEN);
  861. }
  862.  
  863. /******************************************************************************
  864. *
  865. * Funktion     : Fenster mit Maus schließen (mouse_win_zu)
  866. * --------------
  867. *
  868. * Beschreibung : Offensichtlich kann während der Maus-Routine keine andere
  869. *                Maus-Routine installiert werden. Das hat zur Folge, daß
  870. *                beim Ausführen der Mausfunktion "Fenster schließen" im
  871. *                Falle der Ausführung der Funktion ja_nein dort keine
  872. *                neue Maus-Routine installiert werden kann, wenn die alte
  873. *                Maus-Routine noch läuft.
  874. *                Die äußerst unschöne Lösung, die nach Verbesserung schreit,
  875. *                ist folgende:
  876. *                In den Tastaturpuffer wird der Code für das Kommando
  877. *                "Fenster schließen" geschrieben.
  878. *                Dann wird die Maus-Routine verlassen. Während der Ausführung
  879. *                des Kommandos ist die alte Maus-Routine sowieso gesperrt und
  880.                 die neue kann bedenkenlos installiert werden.
  881. *
  882. ******************************************************************************/
  883.  
  884. void mouse_win_zu()
  885. {
  886. #ifdef OS2
  887.   hide_show (MOUSE_HIDE);
  888.   do_win_zu(FALSE);
  889.   hide_show (MOUSE_SHOW);
  890. #else
  891.   int kom_nr=0, /* Nummer des Kommandos do_win_zu */
  892.       i;        /* Zum Durchlaufen des Kommandostrings */
  893.   short int *key_buff_in = (short int *) 0x41C,
  894.         *key_buff    = (short int *) 0x41E; /* Tastaturpuffer */
  895.  
  896.   /* Zuerst den Index des Kommandos "Fenster schließen" ermitteln */
  897.   while(funktion[kom_nr] != do_win_zu && kom_nr++ <= mc_index);
  898.  
  899.   /* Jetzt Schreibadresse in Tastaturpuffer ermitteln: */
  900.   key_buff += (*key_buff_in - 0x1E) / 2;
  901.   for(i=0;i<comm_feld[kom_nr].blen;i++)
  902.   {
  903.     *key_buff++ = comm_feld[kom_nr].befehl[i];
  904.     if(key_buff == (short int *) 0x43E) /* Am Ende wrap around */
  905.       key_buff = (short int *) 0x41E;
  906.   }
  907.   *key_buff_in = FP_OFF(key_buff) - 0x400;
  908. #endif
  909. }
  910.  
  911. /******************************************************************************
  912. *
  913. * Funktion     : Mit Maus nach rechts scrollen (msr)
  914. * --------------
  915. *
  916. * Beschreibung : Der Mauszeiger wird versteckt. Dann wird der Text im Fenster
  917. *                nach rechts geschoben und nötigenfalls der Cursor angepaßt.
  918. *                Dann wird setz_cursor aufgerufem imd der Mauszeiger wieder
  919. *                angezeigt.
  920. *                Der Verschiebe-Vorgang wird solange wiederholt, bis kein
  921. *                Mausknopf mehr gedrückt ist.
  922. *
  923. ******************************************************************************/
  924.  
  925. void msr()
  926. {
  927. #ifdef OS2
  928.   mouse_type m;
  929.   short int wait = 0; /* auf Mausereignisse warten */
  930. #endif
  931.  
  932.   hide_show(MOUSE_HIDE); /* Mauszeiger verstecken */
  933. #ifdef OS2
  934.   MouReadEventQue (&m, &wait, mouse_handle);
  935.   while ((m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT1_MOVE
  936.                | MOUSE_BUT2_MOVE))
  937.        || (!m.button_status && !m.x && !m.y && !m.time)) /* kein Event */
  938. #else
  939.   while(get_mouse()->button_status & (MOUSE_BUT1 | MOUSE_BUT2))
  940. #endif
  941.   {
  942.     text_right();          /* Text nach rechts scrollen */
  943.     /* Falls Cursor am rechten Rand "rausgefallen", dann eins nach links */
  944.     if(akt_winp->screencol >= akt_winp->ws_col + akt_winp->dx)
  945.       left();
  946.     setz_cursor(W_AKT);
  947. #ifdef OS2
  948.     MouReadEventQue (&m, &wait, mouse_handle);
  949. #endif
  950.   }
  951.   hide_show(MOUSE_SHOW);
  952. }
  953.  
  954. /******************************************************************************
  955. *
  956. * Funktion     : Mit Maus nach links scrollen (msl)
  957. * --------------
  958. *
  959. * Beschreibung : Der Mauszeiger wird versteckt. Dann wird der Text im Fenster
  960. *                nach links geschoben und nötigenfalls der Cursor angepaßt.
  961. *                Dann wird setz_cursor aufgerufem imd der Mauszeiger wieder
  962. *                angezeigt.
  963. *                Der Verschiebe-Vorgang wird solange wiederholt, bis kein
  964. *                Mausknopf mehr gedrückt ist.
  965. *
  966. ******************************************************************************/
  967.  
  968. void msl()
  969. {
  970. #ifdef OS2
  971.   mouse_type m;
  972.   short int wait = 0; /* auf Mausereignisse warten */
  973. #endif
  974.  
  975.   hide_show(MOUSE_HIDE); /* Mauszeiger verstecken */
  976. #ifdef OS2
  977.   MouReadEventQue (&m, &wait, mouse_handle);
  978.   while ((m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT1_MOVE
  979.                | MOUSE_BUT2_MOVE))
  980.        || (!m.button_status && !m.x && !m.y && !m.time)) /* kein Event */
  981. #else
  982.   while(get_mouse()->button_status & (MOUSE_BUT1 | MOUSE_BUT2))
  983. #endif
  984.   {
  985.     text_left();          /* Text nach links scrollen */
  986.     /* Falls Cursor am linken Rand "rausgefallen", dann eins nach rechts */
  987.     if(akt_winp->screencol < akt_winp->ws_col)
  988.       right();
  989.     setz_cursor(W_AKT);
  990. #ifdef OS2
  991.     MouReadEventQue (&m, &wait, mouse_handle);
  992. #endif
  993.   }
  994.   hide_show(MOUSE_SHOW);
  995. }
  996.  
  997. /******************************************************************************
  998. *
  999. * Funktion     : Mit Maus nach oben scrollen (msu)
  1000. * --------------
  1001. *
  1002. * Beschreibung : Der Mauszeiger wird versteckt. Dann wird der Text im Fenster
  1003. *                nach oben geschoben und nötigenfalls der Cursor angepaßt.
  1004. *                Dann wird setz_cursor aufgerufem imd der Mauszeiger wieder
  1005. *                angezeigt.
  1006. *                Der Verschiebe-Vorgang wird solange wiederholt, bis kein
  1007. *                Mausknopf mehr gedrückt ist.
  1008. *
  1009. ******************************************************************************/
  1010.  
  1011. void msu()
  1012. {
  1013. #ifdef OS2
  1014.   mouse_type m;
  1015.   short int wait = 0; /* auf Mausereignisse warten */
  1016. #endif
  1017.  
  1018.   hide_show(MOUSE_HIDE);  /* Mauszeiger verstecken */
  1019. #ifdef OS2
  1020.   MouReadEventQue (&m, &wait, mouse_handle);
  1021.   while (((m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT1_MOVE
  1022.                | MOUSE_BUT2_MOVE))
  1023.        || (!m.button_status && !m.x && !m.y && !m.time)) /* kein Event */
  1024. #else
  1025.   while(get_mouse()->button_status & (MOUSE_BUT1 | MOUSE_BUT2)
  1026. #endif
  1027.   && akt_winp->ws_line < akt_winp->maxline)
  1028.   {
  1029.     akt_winp->ws_line++; /* dann Nummer der ersten sichtbaren Zeile erhoehen */
  1030.     text_up(0);          /* gesamten Fenstertext um 1 Zeile nach oben */
  1031.     if(akt_winp->textline < akt_winp->ws_line) /* Falls Cursor in oberster */
  1032.       down();            /* Zeile, dann Cursor um 1 Zeile nach unten bewegen */
  1033.     setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  1034. #ifdef OS2
  1035.     MouReadEventQue (&m, &wait, mouse_handle);
  1036. #endif
  1037.   }
  1038.   hide_show(MOUSE_SHOW);
  1039. }
  1040.  
  1041. /******************************************************************************
  1042. *
  1043. * Funktion     : Mit Maus nach unten scrollen (msd)
  1044. * --------------
  1045. *
  1046. * Beschreibung : Der Mauszeiger wird versteckt. Dann wird der Text im Fenster
  1047. *                nach unten geschoben und nötigenfalls der Cursor angepaßt.
  1048. *                Dann wird setz_cursor aufgerufem imd der Mauszeiger wieder
  1049. *                angezeigt.
  1050. *                Der Verschiebe-Vorgang wird solange wiederholt, bis kein
  1051. *                Mausknopf mehr gedrückt ist.
  1052. *
  1053. ******************************************************************************/
  1054.  
  1055. void msd()
  1056. {
  1057. #ifdef OS2
  1058.   mouse_type m;
  1059.   short int wait = 0; /* auf Mausereignisse warten */
  1060. #endif
  1061.  
  1062.   hide_show(MOUSE_HIDE); /* Mauszeiger verstecken */
  1063. #ifdef OS2
  1064.   MouReadEventQue (&m, &wait, mouse_handle);
  1065.   while (((m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT1_MOVE
  1066.                | MOUSE_BUT2_MOVE))
  1067.        || (!m.button_status && !m.x && !m.y && !m.time)) /* kein Event */
  1068. #else
  1069.   while(get_mouse()->button_status & (MOUSE_BUT1 | MOUSE_BUT2)
  1070. #endif
  1071.   && akt_winp->ws_line)
  1072.   {
  1073.     akt_winp->ws_line--; /* Nummer der ersten sichtbaren Zeile dekrementieren */
  1074.     text_down(0);        /* Text ab Zeile 0 (ganzes Fenster) um 1 nach unten  */
  1075.     if(akt_winp->textline >= akt_winp->ws_line + akt_winp->dy)
  1076.       up(); /* Stand Cursor in letzter Schirmzeile, Cursor 1 Zeile hoch */
  1077.     setz_cursor(W_AKT);        /* Cursor an richtige Position */
  1078. #ifdef OS2
  1079.     MouReadEventQue (&m, &wait, mouse_handle);
  1080. #endif
  1081.   }
  1082.   hide_show(MOUSE_SHOW);
  1083. }
  1084.  
  1085. /******************************************************************************
  1086. *
  1087. * Funktion     : Fenstergröße mit Maus togglen (mouse_tog_size)
  1088. * --------------
  1089. *
  1090. * Beschreibung : Diese Routine wird aufgerufen, wenn der Benutzer mit der
  1091. *                Maus auf die obere rechte Fensterecke geklickt hat. Es
  1092. *                wird die Fenstergröße korrekt eingestellt. Im Falle von OS2
  1093. *                muß man anschließend noch auf das Loslassen des Mausknopfs
  1094. *                warten, da dies sonst als weiteres Ereignis in der Queue
  1095. *                landet.
  1096. *
  1097. ******************************************************************************/
  1098.  
  1099. void mouse_tog_size()
  1100. {
  1101.   mouse_type m;
  1102.   short int wait = 1; /* Auf Mausereignis warten */
  1103.  
  1104.   hide_show(MOUSE_HIDE);
  1105.   do_toggle_size();
  1106.   hide_show(MOUSE_SHOW);
  1107. #ifdef OS2            /* Im Fall von OS2 auf Loslassen des Knopfes warten */
  1108.   do
  1109.   {
  1110.     MouReadEventQue (&m, &wait, mouse_handle);
  1111.   } while (m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT3
  1112.      |  MOUSE_BUT1_MOVE | MOUSE_BUT2_MOVE | MOUSE_BUT3_MOVE));
  1113. #endif
  1114. }
  1115.  
  1116. /******************************************************************************
  1117. *
  1118. * Funktion     : Maus-Routine (mouse_routine)
  1119. * --------------
  1120. *
  1121. * Beschreibung : Diese Routine wird angesrpugen, wenn mit set_mouse_int eine
  1122. *                Event-Mask ungleich 0 eingetragen wurde und das entsprechende
  1123. *                Ereignis eingetreten ist.
  1124. *                Diese Funktion führt dann die entsprechenden Mausfunktionen
  1125. *                aus.
  1126. *
  1127. ******************************************************************************/
  1128.  
  1129. void mouse_routine(
  1130. #ifdef OS2
  1131.            mouse_type *m
  1132. #endif
  1133.           )
  1134. {
  1135. #ifdef OS2  /* Wurde einer der Knöpfe gedrückt, oder hat man nur eine
  1136.            Message "Losgelassen" empfangen? */
  1137.   if (m->button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT3))
  1138.   {
  1139. #else
  1140.   mouse_type *m;    /* Mausstatus */
  1141.  
  1142.   asm push ds;
  1143.   asm push es;
  1144.   asm mov  ax,DGROUP;
  1145.   asm mov  es,ax;
  1146.   asm mov  ds,ax;
  1147.  
  1148. /*  outportb(32,(char) 32); Interrupt für beendet erklären, (nicht auf 386)*/
  1149.       /* damit z.B. im Schneider PC Maus wieder erkannt wird. */
  1150.   m = get_mouse();  /* Mauskoordinaten und Knopfstatus einlesen */
  1151. #endif
  1152.   check_buff();     /* Pufferinhalt in Text uebernehmen       */
  1153.   if(pos_to_win(m->x,m->y) != akt_winp) /* Klick auf aktuelles Fenster? */
  1154.   {                     /* Nein: */
  1155.     hide_show(MOUSE_HIDE); /* Maus solange verstecken */
  1156.     kopf(W_NOTAKT);     /* Altes Fenster als inaktiv markieren */
  1157.     rahmen(W_NOTAKT);
  1158.     wrefresh(akt_winp->winp);
  1159.     sw_pos(m->x,m->y);  /* Zum Fenster wechseln */
  1160.     show_win(W_AKT);    /* Fenster neu zeichnen */
  1161.     hide_show(MOUSE_SHOW); /* Maus wieder anzeigen */
  1162.   }
  1163.   switch(pos_to_button(m))
  1164.   {
  1165.     case MOUSE_TEXT        : set_cursor_or_mark_block(m); break;
  1166.     case MOUSE_KOPF        : mouse_movewin(m); break;
  1167.     case MOUSE_SIZE        : mouse_sizewin(m); break;
  1168.     case MOUSE_CLOSE       : mouse_win_zu(); break;
  1169.     case MOUSE_TOG_SIZE    : mouse_tog_size(); break;
  1170.  
  1171.     case MOUSE_SCROLL_UP   : msu(); break;
  1172.     case MOUSE_SCROLL_DOWN : msd(); break;
  1173.     case MOUSE_SCROLL_RIGHT: msr(); break;
  1174.     case MOUSE_SCROLL_LEFT : msl(); break;
  1175.   }
  1176.  
  1177. #ifdef OS2
  1178.   }
  1179. #else
  1180.   asm pop  es;
  1181.   asm pop  ds;
  1182. #endif
  1183. }
  1184.  
  1185. /******************************************************************************
  1186. *
  1187. * Funktion     : Maus-Routine für Funktion ja_nein (jn_mouse_routine)
  1188. * --------------
  1189. *
  1190. * Beschreibung : Diese Routine wird angesrpugen, wenn mit mouse_jn_init die
  1191. *                Maus aktiviert wurde und das entsprechende Ereignis
  1192. *                eingetreten ist. (DOS-Fall)
  1193. *                Bei OS/2 wird diese Funktion als ein eigener Thread
  1194. *                gestartet. Führt ein Maus-Ereignis zum Setzen der Variablen
  1195. *                mouse_jn, so wird der Thread beendet. Ansonsten muß der
  1196. *                Thread extern beendet werden (DosKillThread), falls
  1197. *                die JN-Antwort von anderswo erhalten wurde.
  1198. *
  1199. *                Diese Funktion setzt dann gemäß dem gedrückten Mausknopf
  1200. *                die globale Variable mouse_jn auf KLICK_LEFT bzw.
  1201. *                KLICK_RIGHT. 
  1202. *
  1203. ******************************************************************************/
  1204.  
  1205. void jn_mouse_routine()
  1206. {
  1207. #ifdef OS2
  1208.   mouse_type m;
  1209.   short int wait = 0; /* Auf Mausereignis warten */
  1210.  
  1211.   while (mouse_active && mouse_jn == NO_KLICK)
  1212.   {
  1213.     MouReadEventQue (&m, &wait, mouse_handle);
  1214.     if (!m.time && !m.button_status) /* Kein Ereignis? Dann 10 ms warten */
  1215.       DosSleep (10);
  1216.     else
  1217.       if (m.button_status & (MOUSE_BUT1 | MOUSE_BUT1_MOVE))
  1218.       {
  1219. /*      DosSleep(200);    eee ohne diese Zeile terminiert in einigen Fällen
  1220.               der mouse_thread nicht: Wenn beispielsweise der
  1221.               Editor durch "Beenden ohne Sichern" verlassen
  1222.               wird, die Sicherheitsabfrage jedoch mit der Maus
  1223.               beantwortet wird, so hängt der mouse_thread
  1224.               ohne diese Zeile... */
  1225.     mouse_jn = KLICK_LEFT;
  1226.       }
  1227.       else if (m.button_status & (MOUSE_BUT2 | MOUSE_BUT2_MOVE))
  1228.     mouse_jn = KLICK_RIGHT;
  1229.   }
  1230. #else
  1231.   int event; /* Für Ablage des eingetretenen Ereignisses */
  1232.  
  1233.   asm push ds;
  1234.   asm push es;
  1235.   asm mov  bx,DGROUP;
  1236.   asm mov  es,bx;
  1237.   asm mov  ds,bx;
  1238.   event = _AX;
  1239.   mouse_jn = event & 8 ? KLICK_RIGHT : KLICK_LEFT;
  1240.   asm pop  es;
  1241.   asm pop  ds;
  1242. #endif
  1243. }
  1244.  
  1245. /******************************************************************************
  1246. *
  1247. * Funktion     : Mouse-Interrupt aktivieren/sperren (mouse_jn_init)
  1248. * --------------
  1249. *
  1250. * Parameter    : on_off    :
  1251. *                  Typ          : int
  1252. *                  Wertebereich : TRUE, FALSE
  1253. *                  Bedeutung    : TRUE : jn_mouse_routine aktivieren
  1254. *                                 FALSE: jn_mouse_routine deaktivieren
  1255. *
  1256. * Beschreibung : Mittels des Mausinterrupts 51, Funktion 12 wird die
  1257. *                Funktion jn_mouse_routine als anzuspringende Funktion
  1258. *                eingetragen. Die Event-Mask wird auf rechten Knopf +
  1259. *                linken Knopf gesetzt, falls aktiviert wird, auf 0 sonst.
  1260. *
  1261. ******************************************************************************/
  1262.  
  1263. void mouse_jn_init(on_off)
  1264. int on_off;
  1265. {
  1266. #ifdef OS2
  1267.   mouse_jn_active = on_off; /* mouse_jn soll auch in der "normalen"
  1268.                    Mouse-Kontrollschleife korrekt gesetzt
  1269.                    werden. */
  1270.   if (on_off)
  1271.   {
  1272.     mouse_jn = NO_KLICK;
  1273.     /* eigener Thread für Maus-JN */
  1274.     mouse_jn_ThreadID = _beginthread (jn_mouse_routine, 0, 20000, 0);
  1275.   }
  1276.   /* else-part nicht nötig, da jn_mouse_routine sich selbst beendet, wenn
  1277.      mouse_jn_active=FALSE festgestellt wird. */
  1278. #else
  1279.   union  REGS  regs;
  1280.   struct SREGS sregs;
  1281.  
  1282.   /* Mauszeiger löschen, falls Maus demaskiert wird, sonst */
  1283.   /* Mauszeiger anzeigen */
  1284.   if(on_off) /* Bei Initialisierung: */
  1285.     mouse_jn = NO_KLICK; /* Variable initialisieren */
  1286.   hide_show(on_off ? MOUSE_SHOW : MOUSE_HIDE);
  1287.   regs.x.ax  = 12;
  1288.   regs.x.cx  = on_off ? MOUSE_MASK : 0;
  1289.   regs.x.dx  = FP_OFF(jn_mouse_routine);
  1290.   sregs.es   = FP_SEG(jn_mouse_routine);
  1291.   int86x(51,®s,®s,&sregs);
  1292. #endif
  1293. }
  1294.  
  1295. /******************************************************************************
  1296. *
  1297. * Funktion     : Mouse-Interrupt aktivieren/sperren (set_mouse_int)
  1298. * --------------
  1299. *
  1300. * Parameter    : event_mask :
  1301. *                  Typ          : int
  1302. *                  Wertebereich : 0-31
  1303. *                  Bedeutung    : Bit 0 : Mausbewegung melden
  1304. *                                 Bit 1 : Druck linker Mausknopf melden
  1305. *                                 Bit 2 : Lösen linker Mausknopf melden
  1306. *                                 Bit 3 : Druck rechter Mausknopf melden
  1307. *                                 Bit 4 : Lösen linker Mausknopf melden
  1308. *
  1309. * Beschreibung : Mittels des Mausinterrupts 51, Funktion 12 wird die
  1310. *                Funktion mouse_routine als anzuspringende Funktion
  1311. *                eingetragen. Die Event-Mask wird gesetzt.
  1312. *
  1313. ******************************************************************************/
  1314.  
  1315. #ifndef OS2
  1316. void set_mouse_int(event_mask)
  1317. int event_mask;
  1318. {
  1319.   union  REGS  regs;
  1320.   struct SREGS sregs;
  1321.  
  1322.   /* Mauszeiger löschen, falls Maus demaskiert wird, sonst */
  1323.   /* Mauszeiger anzeigen */
  1324.   hide_show(event_mask ? MOUSE_SHOW : MOUSE_HIDE);
  1325.   regs.x.ax  = 12;
  1326.   regs.x.cx  = event_mask; /* Linken Mausknopf melden */
  1327.   regs.x.dx  = FP_OFF(mouse_routine);
  1328.   sregs.es   = FP_SEG(mouse_routine);
  1329.   int86x(51,®s,®s,&sregs);
  1330. }
  1331. #endif
  1332.  
  1333. /******************************************************************************
  1334. *
  1335. * Funktion     : Maus initialisieren und abfragen (mouse_thread) (Nur OS/2!!!)
  1336. * --------------
  1337. *
  1338. * Beschreibung : Es werden die Attribute des Maus-Cursors festgelegt, der
  1339. *                Maus-Cursor wird eingeschaltet, als Events sollen Druck des
  1340. *                linken oder rechten Mausknopfs erkannt werden.
  1341. *                Der Zähler sleep_time gibt die Anzahl der Mikrosekunden an,
  1342. *                die zwischen zwei Abfragen gewartet werden soll. Dieser
  1343. *                Zähler wird nach einem gefundenen Mausereignis auf 0 gesetzt,
  1344. *                da weitere Mausereignisse erwartet werden. Schnell nach-
  1345. *                folgende Ereignisse werden somit nahezu verzögerungsfrei be-
  1346. *                arbeitet, während nach längerer Zeit eine maximale Zeit
  1347. *                von 1/10 s bis zur Bearbeitung des Ereignisses vergehen kann.
  1348. *                Durch diese Technik wird trotz des Pollings die Systemaus-
  1349. *                lastung gering gehalten.
  1350. *
  1351. ******************************************************************************/
  1352.  
  1353. #ifdef OS2
  1354. void mouse_thread ()
  1355. {
  1356.   short int  wait = 0,            /* nicht auf Ereignisse warten */
  1357.          mask = MOUSE_MASK;
  1358.   int        sleep_time = 0;      /* sleep in us zwischen zwei Aufrufen */
  1359.   mouse_type event;
  1360.  
  1361.   MouOpen (NULL, &mouse_handle);  /* Maus "öffnen" */
  1362.   hide_show (MOUSE_SHOW);
  1363.   MouSetEventMask (&mask, mouse_handle);
  1364.   while (mouse_active)
  1365.   {
  1366.     DosSleep (sleep_time/1000); /* Zwischen Ereignissen warten */
  1367.     if (sleep_time < 100000)    /* Auf maximal 100 ms erhöhen */
  1368.       sleep_time++;
  1369.     MouReadEventQue (&event, &wait, mouse_handle);
  1370.     if (event.time || event.button_status) /* Ereignis ? */
  1371.     {
  1372.       sleep_time = 0;      /* Wartezeit wieder von 0 beginnen lassen */
  1373.       if (mouse_jn_active)
  1374.       { /* Nur das Flag mouse_jn korrekt besetzen, dazu muß nicht der
  1375.        Semaphor angefordert werden. */
  1376.     if (event.button_status & (MOUSE_BUT1 | MOUSE_BUT1_MOVE))
  1377.       mouse_jn = KLICK_LEFT;
  1378.     if (event.button_status & (MOUSE_BUT2 | MOUSE_BUT2_MOVE))
  1379.       mouse_jn = KLICK_RIGHT;
  1380.       }
  1381.       else /* mouse_jn nicht aktiv, also "richtiges" Kommando ausführen */
  1382.       {
  1383.     DosRequestMutexSem (sem_handle, -1); /* ohne Timeout auf Semaphor warten */
  1384.     mouse_routine (&event);
  1385.     DosReleaseMutexSem (sem_handle);     /* Semaphor wieder freigeben */
  1386.       }
  1387.     }
  1388.   }
  1389.   if (mouse_jn_ThreadID)
  1390.     DosWaitThread (&mouse_jn_ThreadID, DCWW_WAIT);
  1391.   MouClose (mouse_handle);
  1392. }
  1393. #endif
  1394.  
  1395. /******************************************************************************
  1396. *
  1397. * Funktion     : Maus initialisieren (init_mouse)
  1398. * --------------
  1399. *
  1400. * Beschreibung : Es werden die Attribute des Maus-Cursors festgelegt, der
  1401. *                Maus-Cursor wird eingeschaltet, die Maus-Routine eingebunden
  1402. *                und so eingestellt, daß sie durch Druck auf den linken
  1403. *                Mausknopf aktiviert wird.
  1404. *
  1405. ******************************************************************************/
  1406.  
  1407. void init_mouse()
  1408. {
  1409. #ifdef OS2
  1410.   /* Starte eigenen Mouse-Thread */
  1411.   mouse_active = TRUE;
  1412.   mouse_ThreadID = _beginthread (mouse_thread, 0, 20000, 0); 
  1413. #else
  1414.   /* Ruft die Maus-Funktion 12 auf, wodurch der Vektor der User-Routine */
  1415.   /* auf die Funktion mouse_routine gesetzt werden soll. */
  1416.   union  REGS  regs;
  1417.   struct SREGS sregs;
  1418.  
  1419.   regs.x.ax  = 10;  /* Set Text Cursor */
  1420.   regs.x.bx  = 0;   /* Software-Cursor */
  1421.   regs.x.cx  = 0x77ff;  /* Screen Mask */
  1422.   regs.x.dx  = 0x7700;  /* Cursor Mask */
  1423.   int86(51,®s,®s);
  1424.   regs.x.ax  = 7;   /* Set Minimum and Maximum X-Cursor Position */
  1425.   regs.x.cx  = 0;
  1426.   regs.x.dx  = 8*(COLS-1);
  1427.   int86(51,®s,®s);
  1428.   regs.x.ax  = 8;   /* Set Minimum and Maximum Y-Cursor Position */
  1429.   regs.x.cx  = 0;
  1430.   regs.x.dx  = 8*(LINES-1);
  1431.   int86(51,®s,®s);
  1432. #endif
  1433. }
  1434.